#pragma once

#include "fxcc/core/graph/common/ImageMipmap.h"
#include "fxcc/core/graph/common/Type.h"
#include "fxcc/core/Base.h"

namespace fxcc
{
	namespace graph
	{
		namespace common
		{

			struct FXCC_API Texture2DJack :public fxcc::Base
			{
				struct Desc
				{
					fxcc::graph::common::ImageMipmap::Desc m_WICConfig;

					std::string m_DDSPath;

					fxcc::graph::common::ImageMipmap::MipMapData m_MipmapData;

					fxcc::graph::common::SamplerType m_SampleType{ fxcc::graph::common::SamplerType::_sampler_2d_default_ };

					glm::vec2 m_TexStartPos{ 0,0 };
					
					glm::vec2 m_TexOffsetSize{ 1,1 };

					bool m_CreateRTV{ false };

					bool m_DepthStencilMap{ false };

					Desc() {};

					std::string GetPath() const
					{
						switch (m_Type)
						{
						case fxcc::graph::common::Texture2DJack::Desc::_WIC_:
							return m_WICConfig.m_wicPath;
						case fxcc::graph::common::Texture2DJack::Desc::_DDS_:
							return m_DDSPath;
						case fxcc::graph::common::Texture2DJack::Desc::_AllOC_:
							return "";
						default:
							return "";
						}
					}

					Desc(const ImageMipmap::Desc& wicDesc) :m_WICConfig(wicDesc), m_Type(Type::_WIC_)
					{
					}
					Desc(const std::string& ddsPath) :m_DDSPath(ddsPath), m_Type(Type::_DDS_)
					{

					}
					bool SetPath(const std::string& path, int wicReq = 0, int hdr = 0)
					{
						static std::vector<std::string> wicPaths = {

						".PNG",".png",
						".JPG",".jpg",
						".BMP",".bmp",
						};

						std::string suffix = fxcc::Base::GetSuffix(path);
						if (suffix == ".dds" || suffix == ".DDS")
						{
							SetDDS(path);
							return true;
						}
					
						if (fxcc::Base::UUIDsContain(wicPaths, suffix))
						{
							SetWIC(path, wicReq, hdr);
							return true;
						}
						return false;

					}
					bool SetWIC(const std::string& wicPath, int req = 0, int hdr = 0, bool flipY = 0)
					{
						m_WICConfig.m_wicHdr = hdr;
						m_WICConfig.m_wicPath = fxcc::Base::normalizePath(wicPath);
						m_WICConfig.m_wicReq = req;
						m_WICConfig.m_WICFlipY = flipY;
						m_Type = (Type::_WIC_);
						
						return fs::exists(wicPath);
					}
					bool SetDDS(const std::string& ddsPath)
					{
						m_DDSPath = fxcc::Base::normalizePath(ddsPath);
						m_Type = (Type::_DDS_);

						return fs::exists(m_DDSPath);

					}

					Desc(const fxcc::graph::common::ImageMipmap::MipMapData& mipmapData):m_MipmapData(mipmapData),m_Type(Type::_AllOC_)
					{

					}
					enum Type
					{
						_WIC_, _DDS_, _AllOC_
					} m_Type;

					bool IsWIC() const
					{
						return m_Type == Type::_WIC_;
					}
					bool IsDDS() const
					{
						return m_Type == Type::_DDS_;
					}
					bool IsAlloc() const
					{
						return m_Type == Type::_AllOC_;
					}

					bool operator<(const Desc& other) const {
						return std::tie(m_Type, m_DDSPath, m_SampleType, m_WICConfig)
							< std::tie(other.m_Type, other.m_DDSPath, other.m_SampleType, other.m_WICConfig);
					}
					bool operator ==(const Desc& other) const {
						return std::tie(m_Type, m_DDSPath, m_SampleType, m_WICConfig)
							== std::tie(other.m_Type, other.m_DDSPath, other.m_SampleType, other.m_WICConfig);
					}
				} m_Desc;

				Texture2DJack(const Desc& desc = {}) :m_Desc(desc) {}

				virtual ImTextureID GetTextureId() const { return 0; }

				virtual std::string SaveImage(const std::string& nameNoSuffix, int level = 0) const;

				virtual std::string SaveAsHDR(const std::string& hdrPath, int level = 0) const;

				virtual std::string SaveAsBMP(const std::string& bmpPath, int level = 0) const;

				std::string GetImageSuffix() const
				{
					if (m_Desc.m_MipmapData.m_HDR)
					{
						return ".hdr";
					}
					else
					{
						return ".bmp";
					}
				}

				virtual void SetShader(int index) const{
					assert("Null ");
				}

				virtual void Load() {

					assert("Load");
				};
			};
		}
	}

}